package org.vectrics.recruiter.struts.mail;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Set;

import org.apache.ecs.html.Div;
import org.vectrics.SystemException;
import org.vectrics.struts.VectricsTagSupport;

/**
 * @author Mike Moore
 *
 */
public class BulkEmailObjectGraphTag extends VectricsTagSupport {

	private static final long serialVersionUID = -6804921147695246999L;
	
	public static String ACTION_FORM_NAME = "bulkEmailForm";  // Value in struts-config of form.
	public static String CATEGORY_SELECT_COMBO_NAME = "categoryId";
	public static String TEMPLATE_SELECT_COMBO_NAME = "templateId";
	public static String TEMPLATE_SAVED_POPUP_DIV = "template_saved_popup_div";	
	
	public static String FORM_ID = ACTION_FORM_NAME;
	private int lastY = 10;
	/**
	 * 
	 */
	public BulkEmailObjectGraphTag() {
		super();
	}

	
	/* (non-Javadoc)
	 * @see org.vectrics.struts.VectricsTagSupport#makeStartTag()
	 */
	@Override
	protected String makeStartTag() {
		Div mainDiv = new Div();
		log.info("makeStartTag() called");
		
		createGraphTree(mainDiv);
		mainDiv.setPrettyPrint(true);
		mainDiv.setClass("subFont");
/*		
		Div buttonDiv = new Div();
		mainDiv.addElement(buttonDiv);
		
		Form backButtonForm = new Form();
		backButtonForm.setAction("/hrs-intranet/admin/mailer/stage.do");
		Input backButton = new Input();
		backButton.setType(Input.image);
		backButton.setBorder(0);
		backButton.setName("submit");
		backButton.setValue("submit");
		//backButton
		backButton.setSrc("/hrs-intranet/dynagraphic/button.jpg?code=button.std&caption=Back");
		backButtonForm.addElement(backButton);
		mainDiv.addElement(backButtonForm);
		*/
		mainDiv.addElement("<br><br>");
		return (mainDiv.toString());
	}

	private void createGraphTree(Div mainDiv) {
		//StringBuffer html = new StringBuffer();
		RecruitObjectGraph objectGraph = (RecruitObjectGraph)this.getRequest()
			.getSessionAttribute("freemarkerObjectGraph");
		String objectKey = this.getRequest().getParameter("object_key");
		log.info("Object key: " + objectKey);
		if (objectGraph == null)
			throw new SystemException("Could not find freemarkerObjectGraph attached to session");

		Set<String> keys = objectGraph.getKeys();
		Iterator<String> keyIter = keys.iterator();
		while (keyIter.hasNext()) {
			String key = keyIter.next();
			if (key.equals(objectKey)) {
				Object object = objectGraph.getObject(key);
				this.addObjectToGraphDisplay(mainDiv, object, key, 1, 4, key);
			}
		}
	}

	/*
	 * 
	 */
	private void addObjectToGraphDisplay(Div mainDiv, Object object, String key, int depth, 
			int maxDepth, String fullKeyPath) {
		log.info("Adding to objectGraph display: " + key + "  Depth: " 
				+ depth + "  Object Type: " + object.getClass().getName());
		if (depth > maxDepth) {
			return;
		}

		String indentStr = "*";
		//for (int d = 0; d < depth; d++) {
		//	indentStr  += "*&nbsp;";
		//}
		
		String objectValue = null;
		try {
			objectValue = object.toString();
		} catch (Exception ex) {
			log.warn("Exception finding object value: " + fullKeyPath + " - " + ex.getMessage());
		}
		
		String valueStr = "";
		if (showValueForKey(key, fullKeyPath)) {
			valueStr = " = " + objectValue;
		}

		Div nodeDiv = new Div();
		mainDiv.addElement(nodeDiv);
		
		int leftIndent = depth * 15;
		nodeDiv.setStyle("position:relative;width:700");
		/*
		Table table = new Table();
		Row row = table.addRow();
		Cell cell = row.addCell();
		Cell contentCell = row.addCell();
		contentCell.
		*/
		Div contentDiv = new Div();
		nodeDiv.addElement(contentDiv);
		contentDiv.setStyle("position:relative;width:400;left:" + leftIndent + ";top:" + this.lastY);
		contentDiv.addElement(indentStr  + "&nbsp;" + fullKeyPath + valueStr);
		
		
		boolean findChildProperties = true;
		if (
			(object instanceof String) ||
			(object instanceof Long) ||
			(object instanceof BigDecimal) ||
			(object instanceof Integer) 
			)
			{
			findChildProperties = false;
		}
		if (findChildProperties) {
			Method[] methods = object.getClass().getDeclaredMethods();
			for (int i = 0; i < methods.length; i++) {
				Method method = methods[i];
				Class returnClass = method.getReturnType();
				String methodName = method.getName();
				if (methodName.startsWith("get")) {	
					String propertyName = methodName.substring(3);
					if (propertyName.length() > 1) {
						propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
					} else {
						propertyName = propertyName.substring(0, 1).toLowerCase();
					}
					boolean ignore = false;
					if (
						(propertyName.equals("javaLocale")) || 
						(propertyName.equals("callbacks")) || 
						(propertyName.equals("id")) || 
						(propertyName.equals("password")) ||
						(propertyName.equals("passwordEncrypted")) ||
						(propertyName.equals("bytes")) || 
						(propertyName.equals("lastModifiedDate")) || 
						(propertyName.equals("lastModifiedBy")) || 
						(propertyName.equals("createdDate")) || 
						(propertyName.equals("createdBy")) || 
						(propertyName.equals("createPersonInfo")) || 
						(propertyName.equals("hibernateLazyInitializer")) || 
						(propertyName.equals("voided")) || 
						(propertyName.equals("privileges")) 
						 ) {
						ignore = true;
					}
					
					try {
						if (ignore == false) {
							String objectFullKey = fullKeyPath + "." + propertyName;
							objectFullKey = objectFullKey.trim();
							if (ignoreFullKey(objectFullKey) == false) { 
								Object[] args = new Object[0];
								Object returnObject = method.invoke(object, args);
								if (returnObject != null) {
									this.addObjectToGraphDisplay(mainDiv, returnObject, propertyName, 
											depth + 1, 
											maxDepth, objectFullKey);
								}
							}
						}
					} catch (Exception ex) {
						log.info("Error invoking method on object: " + methodName);
					}
				}
			}
		}
	}
	
	private boolean showValueForKey(String key, String fullKeyPath) {
		boolean showValue = true;
		if (fullKeyPath.contains(".")) {
			if (
				(fullKeyPath.endsWith(".domain")) ||
				(fullKeyPath.endsWith(".person")) ||
				(fullKeyPath.endsWith(".contactInfo")) ||
				(fullKeyPath.endsWith("domain.primaryCompany")) ||
				(fullKeyPath.endsWith(".user"))
			) {
				showValue = true;
			} else {
				
			}
		} else {
			showValue = false;
		}
		return(showValue);
	}

	private boolean ignoreFullKey(String fullKey) {
		boolean ignore = false;
		log.info("Checking fullKey of object graph against ignore patterns: " + fullKey);
		if (
				(fullKey.endsWith("user.person")) ||
				(fullKey.endsWith("personInfo.person")) ||
				(fullKey.endsWith("locale.locale")) ||
				(fullKey.endsWith(".domain.children")) ||
				(fullKey.endsWith("contactInfo.person")) ||
				(fullKey.endsWith("currentStatus.dateStart.time")) ||
				(fullKey.endsWith("dateStart.nanos")) ||
				(fullKey.endsWith(".privilegeGroups")) ||
				(fullKey.endsWith(".systemUser")) ||
				(fullKey.endsWith(".person.locale ")) ||
				(fullKey.endsWith("privilegeGroups")) ||
				(fullKey.endsWith(".userPrivileges")) ||
				(fullKey.endsWith(".passwordEncrypted")) ||
				(fullKey.endsWith("statusList")) 
						) {
			log.info("ignoring key: " + fullKey);
			ignore = true;
		} else {
			log.info("key ok: " + fullKey);
		}
		return(ignore);
	}
	
}
